package com.dyna.web.lock.service;

import com.dyna.utils.RdsUtil;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@NoArgsConstructor(force = true)
@RequiredArgsConstructor
public class LockService {

    private final RedissonClient redissonClient;

    public Object readLock() {
        return RdsUtil.get("lock-test");
    }

    public void writeLock(String text) {
        RReadWriteLock lock = redissonClient.getReadWriteLock("lock-test1");
        RLock rLock = lock.writeLock();
        try {
            // lock.lock(leaseTime, Unit)不设置参数,否则若设置了参数，则到期就释放掉锁。设置了参数才能触发启动Redission的“看门狗”机制(守护线程)
            rLock.lock(1000, TimeUnit.SECONDS);
            RdsUtil.set("test", text);
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }finally {
            try {
                rLock.unlock();
            }catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    private final Object lock = new Object();
    private int counter = 0;
    private final CountDownLatch latch = new CountDownLatch(1); // 发令枪

    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public Boolean contention() {
        new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread-1  持有 lock1");
                try { Thread.sleep(100);  } catch (InterruptedException e) {}
                synchronized (lock2) {  // 等待 lock2（被 Thread-2 持有）
                    System.out.println("Thread-1  获取 lock2");
                }
            }
        }).start();

        new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread-2  持有 lock2");
                synchronized (lock1) {  // 等待 lock1（被 Thread-1 持有）
                    System.out.println("Thread-2  获取 lock1");
                }
            }
        }).start();
        return Boolean.TRUE;
    }

}